home *** CD-ROM | disk | FTP | other *** search
- /*
- * Title:
- * display.c
- *
- * Authors:
- * Michael P. Schenck
- *
- * Purpose:
- * Contains all the routines needed for opening and closing the
- * renderers output screen. This is a custom screen which can
- * be opened in a variety of resolutions. The routines will
- * support more than one bitplane of data, but for the wireframe
- * graphics, no more is needed.
- * A screen clearing function is provided which clears the bitmap
- * of the display that is currently hidden. Output always goes
- * to the hidden screen. A line drawing function will draw a
- * line on the hidden bitplane.
- * A getinput function gets a character from the keyboard. You
- * can tell the function either to wait or to just see if there
- * is a character available and continue.
- * The last function provided is a pause function that waits
- * the duration specified (secs, microsecs).
- *
- * Copyright Info:
- * Copyright (C) 1993, 1994 -- by Michael P. Schenck,
- * (mps4466@ultb.isc.rit.edu)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a copy of the GNU General Public License
- * write to the Free Software Foundation, 675 Mass Ave,
- * Cambridge, MA 02139, USA.
- *
- */
-
- #include <proto/diskfont.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <exec/memory.h>
- #include <stdlib.h>
- #include <math.h>
- #include "/include/errors.h"
- #include "/include/display.h"
-
- /* System startup structures. */
-
- static struct NewScreen newscreen = {
- 0,0,320,200,
- 3,0,0,NULL,CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET,
- NULL,NULL,
- NULL,NULL
- };
-
- static struct NewWindow newwindow = {
- 0,0,320,200,0,0,VANILLAKEY,
- SIMPLE_REFRESH | ACTIVATE | NOCAREREFRESH | BORDERLESS | RMBTRAP,
- NULL,NULL,NULL,NULL,NULL,
- 320,200,320,200,CUSTOMSCREEN
- };
-
- /* Blank pointer data. */
-
- static USHORT chip pointer[22] = {
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
- 0x0000,0x0000,0x0000,0x0000
- };
-
- static long __OSlibversion = 33;
- static struct Window *window = NULL;
- static struct timerequest timermsg;
- static struct MsgPort *treplyport = NULL;
- static UBYTE timeropen,depth;
- static UWORD *colortable,width,height,code;
- static ULONG signalmask,signals,class;
-
- struct Screen *screen = NULL;
- struct BitMap *dbbitmaps[2];
-
- static UWORD bytewidth,blitsize;
- static UBYTE buffered;
-
- /* Assembly blitter functions (rasterasm.a). */
-
- void __asm blitclearmem(register __d0 UWORD blitsize,
- register __a0 APTR clear);
-
- void __asm blitline(register __d0 WORD x0,
- register __d1 WORD y0,
- register __d2 WORD x1,
- register __d3 WORD y1,
- register __d4 UWORD bytewidth,
- register __a0 APTR firstpixel);
-
- struct BitMap *allocatebitmap(void);
- void releasebitmap(struct BitMap *);
- UBYTE getmessage(void);
- void cleanup(void);
-
- /* Opens and initializes the display module. */
-
- UBYTE opendisplay(UWORD *coltable,UWORD swidth,UWORD sheight,UBYTE sdepth)
-
- {
- width = swidth;
- height = sheight;
- depth = sdepth;
- if((dbbitmaps[0] = allocatebitmap()) == NULL)
- return(MEM_ALLOC_FAILURE);
- if((dbbitmaps[1] = allocatebitmap()) == NULL) {
- releasebitmap(dbbitmaps[0]);
- return(MEM_ALLOC_FAILURE);
- }
- newscreen.Width = width;
- newscreen.Height = height;
- newscreen.Depth = depth;
- if (width>320)
- newscreen.ViewModes = HIRES;
- if (height>200)
- newscreen.ViewModes = newscreen.ViewModes | LACE;
- newscreen.CustomBitMap = dbbitmaps[0];
- newwindow.Width = width;
- newwindow.Height = height;
- newwindow.MinWidth = width;
- newwindow.MinHeight = height;
- newwindow.MaxWidth = width;
- newwindow.MaxHeight = height;
- colortable = coltable;
- if ((screen = OpenScreen(&newscreen)) == NULL) {
- cleanup();
- return(OPEN_VIEW_FAILURE);
- }
- screen->RastPort.Flags = DBUFFER;
- newwindow.Screen = screen;
- if ((window = OpenWindow(&newwindow)) == NULL) {
- cleanup();
- return(OPEN_VIEW_FAILURE);
- }
- LoadRGB4(&(screen->ViewPort),colortable,(UBYTE)pow2((double)depth));
- SetPointer(window,pointer,9,16,0,0);
- timeropen = OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *) &timermsg,0);
- if (timeropen) {
- cleanup();
- return(OPEN_VIEW_FAILURE);
- }
- if ((treplyport = (struct MsgPort *) CreatePort(0,0)) == NULL) {
- cleanup();
- return(OPEN_VIEW_FAILURE);
- }
- signalmask = 1L << window->UserPort->mp_SigBit;
-
- bytewidth = width >> 3; /* Width of screen in bytes, for blitter. */
- blitsize = (height << 6)+(width >> 4); /* Blitsize for clearing the screen. */
- buffered = 1; /* Set screen buffer. */
-
- OwnBlitter(); /* Do initial screen clearing. */
- WaitBlit();
- blitclearmem(blitsize,(APTR)dbbitmaps[0]->Planes[0]);
- blitclearmem(blitsize,(APTR)dbbitmaps[1]->Planes[0]);
- DisownBlitter();
-
- return(0);
- }
-
- /* Closes down the display module. */
-
- void closedisplay()
-
- {
- cleanup();
- }
-
- /* Clears the screen. NOTE: The screen is always cleared in displaygraphics(). */
-
- void clearscreen()
-
- {
- OwnBlitter();
- WaitBlit();
- blitclearmem(blitsize,(APTR)dbbitmaps[buffered]->Planes[0]);
- DisownBlitter();
- }
-
- /* Draws a line using the blitter. */
-
- void line(WORD x0, WORD y0, WORD x1, WORD y1)
-
- {
- UBYTE lineinside = TRUE;
-
- OwnBlitter();
- WaitBlit();
-
- /* 2D clipping to the screen. */
-
- if(x0 < 0) {
- if(x1 >= 0) {
- y0 = y0+(y1-y0)*(0-x0)/(x1-x0);
- x0 = 0;
- }
- else
- lineinside = FALSE;
- }
- else if(x1 < 0) {
- y1 = y0+(y1-y0)*(0-x0)/(x1-x0);
- x1 = 0;
- }
- if(x0 >= width) {
- if(x1 < width) {
- y0 = y0+(y1-y0)*(width-x0)/(x1-x0);
- x0 = width-1;
- }
- else
- lineinside = FALSE;
- }
- else if(x1 >= width) {
- y1 = y0+(y1-y0)*(width-x0)/(x1-x0);
- x1 = width-1;
- }
- if(y0 < 0) {
- if(y1 >= 0) {
- x0 = x0+(x1-x0)*(0-y0)/(y1-y0);
- y0 = 0;
- }
- else
- lineinside = FALSE;
- }
- else if(y1 < 0) {
- x1 = x0+(x1-x0)*(0-y0)/(y1-y0);
- y1 = 0;
- }
- if(y0 >= height) {
- if(y1 < height) {
- x0 = x0+(x1-x0)*(height-y0)/(y1-y0);
- y0 = height-1;
- }
- else
- lineinside = FALSE;
- }
- else if(y1 >= height) {
- x1 = x0+(x1-x0)*(height-y0)/(y1-y0);
- y1 = height-1;
- }
-
- /* Blit the line if it is on the screen. */
-
- if(lineinside==TRUE)
- blitline(x0,y0,x1,y1,bytewidth,(APTR)dbbitmaps[buffered]->Planes[0]);
- DisownBlitter();
- }
-
- /* Switch bitmap displays. */
-
- void showgraphics()
- {
- screen->RastPort.BitMap = dbbitmaps[buffered];
- screen->ViewPort.RasInfo->BitMap = dbbitmaps[buffered];
- MakeScreen(screen);
- RethinkDisplay();
-
- if(buffered == 0)
- buffered = 1;
- else
- buffered = 0;
- }
-
- /* Allocate a bitmap. */
-
- struct BitMap *allocatebitmap()
-
- {
- struct BitMap *bitmap;
- UBYTE i;
-
- if ((bitmap = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_CLEAR))!=NULL) {
- InitBitMap(bitmap,depth,width,height);
- for (i=0;i<depth;i++) {
- if((bitmap->Planes[i] = (PLANEPTR)AllocRaster(width,height))==NULL)
- return(NULL);
- }
- }
- else
- return(NULL);
- return(bitmap);
- }
-
- /* Releases a bitmap. */
-
- void releasebitmap(struct BitMap *bitmap)
-
- {
- UBYTE i;
-
- for (i=0;i<depth;i++) {
- FreeRaster(bitmap->Planes[i],width,height);
- FreeMem(bitmap,sizeof(struct BitMap));
- }
- }
-
- /* Waits for input from intuition. */
-
- UBYTE getinput(UBYTE style)
- {
- if(getmessage())
- return((UBYTE)code);
- if(style == WAIT) {
- while(TRUE) {
- signals = Wait(signalmask);
- if (signals & signalmask) {
- if(getmessage())
- return((UBYTE)code);
- }
- }
- }
- else
- return(FALSE);
- }
-
- /* Get an intuition message. If there is one, only looking for keyboard input. */
-
- UBYTE getmessage()
- {
- struct IntuiMessage *message;
-
- if((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != NULL) {
- class = message->Class;
- code = message->Code;
- ReplyMsg((struct Message *)message);
- if(class == VANILLAKEY)
- return(TRUE);
- else
- return(FALSE);
- }
- return(FALSE);
- }
-
- /* Pauses system until time has elapsed. */
-
- void pause(ULONG secs,ULONG microsecs)
-
- {
- timermsg.tr_node.io_Command = TR_ADDREQUEST;
- timermsg.tr_node.io_Message.mn_ReplyPort = treplyport;
- timermsg.tr_time.tv_secs = secs;
- timermsg.tr_time.tv_micro = microsecs;
- DoIO((struct IORequest *) &timermsg);
- }
-
- /* Close everything that has been opened. */
-
- void cleanup(void)
-
- {
- if (treplyport)
- DeletePort(treplyport);
- if (!timeropen)
- CloseDevice((struct IORequest *) &timermsg);
- if (window)
- CloseWindow(window);
- if (screen)
- CloseScreen(screen);
-
- releasebitmap(dbbitmaps[0]);
- releasebitmap(dbbitmaps[1]);
- }
-
-
-